"""
FastAPI依赖项
包括认证、权限检查等依赖
"""

from typing import Optional, List
from fastapi import Depends, HTTPException, status, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_db
from app.models.auth import User
from app.services.auth_service import AuthService
from app.core.logger import logger


# HTTP Bearer 认证方案
security = HTTPBearer(auto_error=False)


class AuthDependency:
    """认证依赖类"""
    
    def __init__(self):
        self.auth_service = AuthService()
    
    async def get_current_user(
        self,
        request: Request,
        db: AsyncSession = Depends(get_db),
        credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
    ) -> User:
        """获取当前认证用户"""
        if not credentials:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="未提供认证令牌",
                headers={"WWW-Authenticate": "Bearer"},
            )
        
        try:
            user = await self.auth_service.get_current_user(db, credentials.credentials)
            
            # 记录用户活动（可选）
            # await self._update_user_activity(db, user, request)
            
            return user
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"获取当前用户失败：{str(e)}")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="认证失败",
                headers={"WWW-Authenticate": "Bearer"},
            )
    
    async def get_current_active_user(
        self,
        request: Request,
        db: AsyncSession = Depends(get_db),
        credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
    ) -> User:
        """获取当前激活用户"""
        # 先获取当前用户
        current_user = await self.get_current_user(request, db, credentials)

        if not current_user.is_active:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="账户未激活"
            )
        return current_user

    async def get_current_superuser(
        self,
        request: Request,
        db: AsyncSession = Depends(get_db),
        credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
    ) -> User:
        """获取当前超级用户"""
        # 先获取当前激活用户
        current_user = await self.get_current_active_user(request, db, credentials)

        if not current_user.is_superuser:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="需要超级用户权限"
            )
        return current_user
    
    def require_permissions(self, permissions: List[str], require_all: bool = False):
        """权限检查装饰器工厂"""
        async def permission_checker(
            current_user: User = Depends(self.get_current_active_user)
        ) -> User:
            """权限检查器"""
            if current_user.is_superuser:
                return current_user
            
            user_permissions = [p.name for p in current_user.get_permissions()]
            
            if require_all:
                # 需要所有权限
                missing_permissions = [p for p in permissions if p not in user_permissions]
                if missing_permissions:
                    raise HTTPException(
                        status_code=status.HTTP_403_FORBIDDEN,
                        detail=f"缺少权限: {', '.join(missing_permissions)}"
                    )
            else:
                # 需要任一权限
                if not any(p in user_permissions for p in permissions):
                    raise HTTPException(
                        status_code=status.HTTP_403_FORBIDDEN,
                        detail=f"需要以下权限之一: {', '.join(permissions)}"
                    )
            
            return current_user
        
        return permission_checker
    
    def require_roles(self, roles: List[str], require_all: bool = False):
        """角色检查装饰器工厂"""
        async def role_checker(
            current_user: User = Depends(self.get_current_active_user)
        ) -> User:
            """角色检查器"""
            if current_user.is_superuser:
                return current_user
            
            user_roles = [r.name for r in current_user.get_active_roles()]
            
            if require_all:
                # 需要所有角色
                missing_roles = [r for r in roles if r not in user_roles]
                if missing_roles:
                    raise HTTPException(
                        status_code=status.HTTP_403_FORBIDDEN,
                        detail=f"缺少角色: {', '.join(missing_roles)}"
                    )
            else:
                # 需要任一角色
                if not any(r in user_roles for r in roles):
                    raise HTTPException(
                        status_code=status.HTTP_403_FORBIDDEN,
                        detail=f"需要以下角色之一: {', '.join(roles)}"
                    )
            
            return current_user
        
        return role_checker
    
    async def _update_user_activity(self, db: AsyncSession, user: User, request: Request):
        """更新用户活动记录（可选功能）"""
        try:
            # 这里可以记录用户的最后活动时间、IP地址等
            # 根据需要实现
            pass
        except Exception as e:
            logger.warning(f"更新用户活动记录失败：{str(e)}")


# 创建全局认证依赖实例
auth_dependency = AuthDependency()

# 常用依赖快捷方式
get_current_user = auth_dependency.get_current_user
get_current_active_user = auth_dependency.get_current_active_user
get_current_superuser = auth_dependency.get_current_superuser

# =============================================
# 新的简化权限检查器（基于权限继承）
# =============================================

# 导入权限继承服务
from app.services.permission_hierarchy_service import (
    require_permission_with_hierarchy,
    require_any_permission_with_hierarchy,
    require_resource_action
)

# 用户管理权限
require_user_view = require_permission_with_hierarchy("user.view")
require_user_manage = require_permission_with_hierarchy("user.manage")
require_user_admin = require_permission_with_hierarchy("user.admin")

# 角色管理权限
require_role_view = require_permission_with_hierarchy("role.view")
require_role_manage = require_permission_with_hierarchy("role.manage")

# 权限管理权限
require_permission_view = require_permission_with_hierarchy("user.view")  # 权限查看归属于用户管理
require_permission_manage = require_permission_with_hierarchy("user.admin")  # 权限管理需要用户管理员权限

# 路由管理权限（归属于系统管理）
require_route_view = require_permission_with_hierarchy("system.admin")
require_route_manage = require_permission_with_hierarchy("system.admin")

# 血缘管理权限
require_lineage_view = require_permission_with_hierarchy("lineage.view")
require_lineage_analyze = require_permission_with_hierarchy("lineage.analyze")
require_lineage_manage = require_permission_with_hierarchy("lineage.manage")

# 任务管理权限
require_task_view = require_permission_with_hierarchy("task.view")
require_task_manage = require_permission_with_hierarchy("task.manage")

# 数据管理员权限
require_data_admin = require_permission_with_hierarchy("data.admin")

# 系统管理员权限
require_system_admin = require_permission_with_hierarchy("system.admin")

# =============================================
# 兼容性权限检查器（保持向后兼容）
# =============================================

# 保留一些常用的组合权限检查，用于过渡期
require_role_manage_with_permissions = require_permission_with_hierarchy("user.admin")  # 简化为用户管理员权限

require_task_view = auth_dependency.require_permissions(["task.view"])
require_task_create = auth_dependency.require_permissions(["task.create"])
require_task_execute = auth_dependency.require_permissions(["task.execute"])
require_task_manage = auth_dependency.require_permissions(["task.manage"])

require_system_config = auth_dependency.require_permissions(["system.config"])
require_system_monitor = auth_dependency.require_permissions(["system.monitor"])
require_system_log = auth_dependency.require_permissions(["system.log"])

# 角色检查快捷方式
require_admin_role = auth_dependency.require_roles(["admin"])
require_analyst_role = auth_dependency.require_roles(["analyst", "admin"], require_all=False)
require_operator_role = auth_dependency.require_roles(["operator", "admin"], require_all=False)


class OptionalAuth:
    """可选认证依赖"""
    
    def __init__(self):
        self.auth_service = AuthService()
    
    async def get_current_user_optional(
        self,
        request: Request,
        db: AsyncSession = Depends(get_db),
        credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
    ) -> Optional[User]:
        """获取当前用户（可选，不强制认证）"""
        if not credentials:
            return None
        
        try:
            user = await self.auth_service.get_current_user(db, credentials.credentials)
            return user if user.is_active else None
        except Exception:
            return None


# 可选认证实例
optional_auth = OptionalAuth()
get_current_user_optional = optional_auth.get_current_user_optional


class RateLimitDependency:
    """限流依赖"""
    
    def __init__(self, max_requests: int = 100, window_seconds: int = 60):
        self.max_requests = max_requests
        self.window_seconds = window_seconds
        # 这里可以集成Redis或其他缓存系统来实现分布式限流
        self._request_counts = {}
    
    async def check_rate_limit(self, request: Request) -> bool:
        """检查限流"""
        # 简单的内存限流实现，生产环境建议使用Redis
        client_ip = request.client.host if request.client else "unknown"
        current_time = int(time.time())
        window_start = current_time - (current_time % self.window_seconds)
        
        key = f"{client_ip}:{window_start}"
        
        if key not in self._request_counts:
            self._request_counts[key] = 0
        
        self._request_counts[key] += 1
        
        if self._request_counts[key] > self.max_requests:
            raise HTTPException(
                status_code=status.HTTP_429_TOO_MANY_REQUESTS,
                detail="请求过于频繁，请稍后再试"
            )
        
        # 清理过期的计数器
        expired_keys = [k for k in self._request_counts.keys() 
                       if int(k.split(':')[1]) < window_start - self.window_seconds]
        for k in expired_keys:
            del self._request_counts[k]
        
        return True


# 限流实例
import time
rate_limiter = RateLimitDependency(max_requests=100, window_seconds=60)
check_rate_limit = rate_limiter.check_rate_limit

# 登录限流（更严格）
login_rate_limiter = RateLimitDependency(max_requests=10, window_seconds=60)
check_login_rate_limit = login_rate_limiter.check_rate_limit


class IPWhitelistDependency:
    """IP白名单依赖"""
    
    def __init__(self, whitelist: List[str] = None):
        self.whitelist = whitelist or []
    
    async def check_ip_whitelist(self, request: Request) -> bool:
        """检查IP白名单"""
        if not self.whitelist:
            return True
        
        client_ip = request.client.host if request.client else "unknown"
        
        # 检查X-Forwarded-For头部
        forwarded_for = request.headers.get("X-Forwarded-For")
        if forwarded_for:
            client_ip = forwarded_for.split(",")[0].strip()
        
        if client_ip not in self.whitelist:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="IP地址不在白名单中"
            )
        
        return True


# IP白名单实例（可根据需要配置）
ip_whitelist = IPWhitelistDependency()
check_ip_whitelist = ip_whitelist.check_ip_whitelist
